package com.bsoft.gol.hcs.visitrecord.dao;

import ctd.persistence.annotation.DAOMethod;
import ctd.persistence.annotation.DAOParam;
import ctd.persistence.support.hibernate.template.AbstractHibernateStatelessResultAction;
import ctd.persistence.support.hibernate.template.HibernateSessionTemplate;
import ctd.persistence.support.hibernate.template.HibernateStatelessResultAction;
import ctd.util.converter.ConversionUtils;
import com.bsoft.gol.hcs.enumcase.FollowTypeEnum;
import org.atag.dao.ext.HibernateExtendDAO;
import org.hibernate.Query;
import org.hibernate.StatelessSession;
import org.hibernate.criterion.CriteriaSpecification;
import org.hibernate.transform.Transformers;
import com.bsoft.gol.hcs.specialist.bean.request.GroupChronicRecordQo;
import com.bsoft.gol.hcs.specialist.bean.response.FactorData;
import com.bsoft.gol.hcs.specialist.bean.response.OperativeRecordResponse;
import com.bsoft.gol.hcs.specialist.bean.response.PatientSearchProcess;
import com.bsoft.gol.hcs.specialist.bean.response.SurgicalInfoResponse;
import com.bsoft.gol.hcs.specialist.entity.PatientSearchRuleDetail;
import com.bsoft.gol.hcs.utils.CommonUtils;
import com.bsoft.gol.hcs.utils.DateUtil;
import org.atag.dao.action.QoHibernateStatelessResultAction;
import org.atag.dao.model.SimplePageInfo;
import com.bsoft.gol.hcs.visitrecord.bean.qo.HospitalVisitsRecordListQo;
import com.bsoft.gol.hcs.visitrecord.bean.vo.HospitalVisitsRecordListVo;
import com.bsoft.gol.hcs.visitrecord.entity.VrSurgicalRecord;

import java.util.*;

/**
 * Created by ChenJij on 2020/9/4.
 */
public abstract class VrSurgicalRecordDAO extends HibernateExtendDAO<VrSurgicalRecord> {
    public VrSurgicalRecordDAO() {
        this.setKeyField("operationRecordId");
    }

    /**
     * @description: 更新满意度调查已完成数量
     * @author: chenJij@bsoft.com.cn
     * @date: 2020/10/9 13:25
     */
    @DAOMethod(sql = "update VrSurgicalRecord set finishNumber=finishNumber+1 where  operationRecordId=:businessId")
    public abstract void updateFinishNumber(@DAOParam("businessId") String businessId);

    @DAOMethod(sql = "delete from VrSurgicalRecord where end_time <:resultDate and delete_flag !='1' ")
    public abstract void deleteSurgicalOverdueData(@DAOParam("resultDate") Date resultDate);

    /**
     * 查询同步数量
     *
     * @param startTime
     * @param endTime
     * @return
     */
    @DAOMethod(sql = "select count(1) from VrSurgicalRecord  where  startTime>=:startTime and startTime<=:endTime")
    public abstract Long getSurgicalRecordByToday(@DAOParam("startTime") Date startTime,
                                                  @DAOParam("endTime") Date endTime);

    /**
     * 更新删除标识
     */
    @DAOMethod(sql = "update VrSurgicalRecord set deleteFlag='1' where  businessId in(:businessIdList) ")
    public abstract void updateDeleteFlag(@DAOParam("businessIdList") List<String> businessIdList);

    @DAOMethod(sql = "from VrSurgicalRecord where businessType=:businessType and visitId=:visitId")
    public abstract List<VrSurgicalRecord> queryVrSurgicalRecordList(@DAOParam("businessType") String businessType,
                                                                     @DAOParam("visitId") String visitId);

    /**
     * 查询所有的病人id
     *
     * @return java.util.List<java.lang.String>
     * @throws
     * @author tongtp
     * @date 2022/6/14 15:15
     */
    public List<String> queryAllPatientId(final List<String> departmentIds) {
        HibernateStatelessResultAction<List<String>> action =
                new AbstractHibernateStatelessResultAction<List<String>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT DISTINCT patient_id AS patientId ");
                        sqlBuilder.append(" FROM vr_surgical_record ");
                        sqlBuilder.append(" WHERE patient_id is not null ");
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            sqlBuilder.append(" and department_id in (:departmentIds) ");
                        }
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            query.setParameterList("departmentIds", departmentIds);
                        }
                        List list = query.list();
                        List<String> voList;
                        if (CommonUtils.isNotEmpty(list)) {
                            voList = list;
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据患者id获取最新的一条数据
     */
    public VrSurgicalRecord getPatientIdAndLastOne(String patientId, String departmentId) {

        HibernateStatelessResultAction<VrSurgicalRecord> action =
                new AbstractHibernateStatelessResultAction<VrSurgicalRecord>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        List departmentIds = null;
                        if (CommonUtils.isNotNull(departmentId)) {
                            departmentIds = Arrays.asList(departmentId.split(","));
                        }
                        StringBuilder builder = new StringBuilder();
                        builder.append(" from VrSurgicalRecord  where  patientId =:patientId ");
                        builder.append(" and startTime is not null");
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            builder.append(" and departmentId in (:departmentIds) ");
                        }
                        builder.append(" order by startTime desc");
                        Query query = ss.createQuery(builder.toString());
                        query.setParameter("patientId", patientId);
                        if (CommonUtils.isNotEmpty(departmentIds)) {
                            query.setParameterList("departmentIds", departmentIds);
                        }
                        // 查询的条数
                        query.setMaxResults(1);
                        // 开始查询的位置
                        query.setFirstResult(0);
                        List<Map<String, Object>> dbList = query.list();
                        if (CommonUtils.isNotEmpty(dbList)) {
                            setResult(ConversionUtils.convert(dbList.get(0), VrSurgicalRecord.class));
                        } else {
                            setResult(null);
                        }
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();

    }

    @DAOMethod(sql = " from VrSurgicalRecord where operationNumber =:operationNumber and organizationId=:organizationId")
    public abstract VrSurgicalRecord getVrSurgicalRecord(@DAOParam("operationNumber") String operationNumber, @DAOParam("organizationId") String organizationId);

    public SimplePageInfo<HospitalVisitsRecordListVo> queryOutpatientVisitRecordList(HospitalVisitsRecordListQo qo) {
        QoHibernateStatelessResultAction<HospitalVisitsRecordListVo, HospitalVisitsRecordListQo> action = new QoHibernateStatelessResultAction(true, qo, HospitalVisitsRecordListVo.class);
        action.setSql(" SELECT {{" +
                " '3' businessType, " +
                " operation_record_id AS businessId, " +
                " organization_id AS organizationId, " +
                " patient_id AS patientId, " +
                " patient_name AS patientName, " +
                " patient_sex AS patientSex, " +
                " patient_age_text AS patientAge, " +
                " department_name AS departmentName, " +
                " survey_number AS surveyNumber, " +
                " finish_number AS finishNumber, " +
                " patient_medical_card_number AS patientMedicalCardNumber, " +
                " patient_medical_card_type AS patientMedicalCardType, " +
                " card_number AS cardNumber, " +
                " card_type AS cardType, " +
                " telephone, " +
                " operation_name AS operationName, " +
                " surgeon_doctor_name AS doctorName, " +
                " start_time AS operationDate }} " +
                "FROM " +
                " vr_surgical_record where 1=1 ");
        action.addCondition(" and patient_name =:patientName ");
        action.addCondition(" and telephone =:telephone ");
        action.addCondition(" and patient_medical_card_number =:patientMedicalCardNumber ");
        action.addCondition(" and organization_id =:organizationId ");
        action.addCondition(" and department_id =:departmentId ");
        action.addCondition(" and surgeon_doctor_id =:doctorId ");
        action.addCondition(" and start_time >=:beginDate ");
        action.addCondition(" and start_time <:endDate ");

        HibernateSessionTemplate.instance().execute(action);
        SimplePageInfo<HospitalVisitsRecordListVo> pageInfo = action.getSimpleResultPage();
        return pageInfo;
    }

    /**
     * 获取手术信息
     *
     * @return
     */
    public List<SurgicalInfoResponse> querySurgicalInfoList() {
        HibernateStatelessResultAction<List<SurgicalInfoResponse>> action =
                new AbstractHibernateStatelessResultAction<List<SurgicalInfoResponse>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT distinct operation_code as operationCode,operation_name as operationName ");
                        sqlBuilder.append("FROM vr_surgical_record ");
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
                        List<Map> list = query.list();
                        List<SurgicalInfoResponse> voList = new ArrayList<>();
                        if (CommonUtils.isNotEmpty(list)) {
                            for (Map map : list) {
                                voList.add(ConversionUtils.convert(map, SurgicalInfoResponse.class));
                            }
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据手术名称获取患者信息
     *
     * @param patientSearchRuleDetail
     * @param recordStartTime
     * @param recordEndTime
     * @return
     */
    public List<PatientSearchProcess> queryPatientBySurgicalRecord(final PatientSearchRuleDetail patientSearchRuleDetail, final Date recordStartTime, final Date recordEndTime) {
        HibernateStatelessResultAction<List<PatientSearchProcess>> action =
                new AbstractHibernateStatelessResultAction<List<PatientSearchProcess>>() {
                    @Override
                    public void execute(StatelessSession ss) throws Exception {
                        StringBuilder sqlBuilder = new StringBuilder();
                        sqlBuilder.append("SELECT a.organization_id as organizationId,a.organization_name as organizationName,a.visit_id AS patientNumber, a.patient_age as patientAge,a.patient_name as patientName, a.patient_sex as patientSex,a.card_number AS cardNumber, ");
                        sqlBuilder.append("a.card_type AS cardType, a.patient_id AS patientId,a.telephone as telephone,(select GROUP_CONCAT(distinct f.chronic_disease_name) from fus_team_chronic_group_record f where a.patient_id = f.patient_id and f.apply_status = '1') AS chronicDiseaseName, ");
                        sqlBuilder.append(" (select GROUP_CONCAT(distinct f.chronic_disease_id) from fus_team_chronic_group_record f where a.patient_id = f.patient_id and f.apply_status = '1') AS chronicDiseaseIds ");
                        sqlBuilder.append("FROM vr_surgical_record a ");
                        sqlBuilder.append("where a.operation_name =:firstConditionName ");
                        if (CommonUtils.isNotEmpty(recordStartTime) && CommonUtils.isNotEmpty(recordEndTime)) {
                            sqlBuilder.append(" and a.end_time >=:recordStartTime and a.end_time <= :recordEndTime");
                        }
                        Query query = ss.createSQLQuery(sqlBuilder.toString());
                        query.setParameter("firstConditionName", patientSearchRuleDetail.getFirstConditionName());
                        if (CommonUtils.isNotEmpty(recordStartTime) && CommonUtils.isNotEmpty(recordEndTime)) {
                            query.setParameter("recordStartTime", DateUtil.dateFormate(recordStartTime, "yyyy-MM-dd"));
                            query.setParameter("recordEndTime", DateUtil.dateFormate(recordEndTime, "yyyy-MM-dd"));
                        }
                        query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
                        List<Map> list = query.list();
                        List<PatientSearchProcess> voList = new ArrayList<>();
                        if (CommonUtils.isNotEmpty(list)) {
                            for (Map map : list) {
                                voList.add(ConversionUtils.convert(map, PatientSearchProcess.class));
                            }
                        } else {
                            voList = new ArrayList<>();
                        }
                        setResult(voList);
                    }
                };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    /**
     * 根据病人id和病种id获取手术信息
     *
     * @param qo
     * @return
     */
    public List<OperativeRecordResponse> queryOperativeInfoListByIdCard(GroupChronicRecordQo qo) {
        HibernateStatelessResultAction<List<OperativeRecordResponse>> action = new AbstractHibernateStatelessResultAction<List<OperativeRecordResponse>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("SELECT operation_code as operativeCode,operation_record_id as operativeRecordId,operation_name as operativeName,end_time as operativeTime  from vr_surgical_record WHERE card_number =:idCard ");
                sqlBuilder.append(" and end_time>=:beginTime and end_time <=:endTime ");
                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameter("idCard", qo.getIdCard());
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("beginTime", qo.getBeginTime()+" 00:00:00");
                }
                if (CommonUtils.isNotEmpty(qo.getBeginTime())){
                    query.setParameter("endTime", qo.getEndTime()+" 23:59:59");
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<OperativeRecordResponse> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, OperativeRecordResponse.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }

    public List<FactorData> executeFactorForOperation(List<String> operateIdList, Date startTime, Date endTime, List<String> patientIdList, Byte isLoopExecute,Long routeDetailId , String followType) {
        HibernateStatelessResultAction<List<FactorData>> action = new AbstractHibernateStatelessResultAction<List<FactorData>>() {
            @Override
            public void execute(StatelessSession ss) throws Exception {
                StringBuilder sqlBuilder = new StringBuilder();
                sqlBuilder.append("select patientId,operationRecordId,operationCode,operationName,operationEndTime,dataSource from (");
                sqlBuilder.append("SELECT patient_id as patientId,operation_record_id operationRecordId,operation_code operationCode,operation_name operationName,");
                sqlBuilder.append("end_time operationEndTime ,'1' as dataSource FROM `vr_surgical_record` ");

                sqlBuilder.append(" WHERE operation_code in (:operationCode)  ");

                if (null != endTime) {
                    sqlBuilder.append("  and  end_time <:endTime ");
                }
                if (null != startTime) {
                    sqlBuilder.append(" and end_time> :startTime");
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    sqlBuilder.append(" and patient_id in (:patientIdList)");
                }

                sqlBuilder.append(") AS  m ");
                //循环执行机制 0 不执行 1 执行
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    sqlBuilder.append(" LEFT JOIN fus_factor_data_record f  ON f.patient_id = m.patientId   AND f.route_detail_id = :routeDetailId AND f.operation_record_id = m.operationRecordId WHERE f.id IS NULL  ");
                }

                Query query = ss.createSQLQuery(sqlBuilder.toString());
                query.setParameterList("operationCode", operateIdList);
                if (null != endTime) {
                    query.setParameter("endTime", endTime);
                }
                if (null != startTime) {
                    query.setParameter("startTime", startTime);
                }
                if (CommonUtils.isNotEmpty(patientIdList)) {
                    query.setParameterList("patientIdList", patientIdList);
                }
                if (FollowTypeEnum.FUS_SPECIALIST.getType().equals(followType) && null != isLoopExecute && isLoopExecute == 1) {
                    query.setParameter("routeDetailId", routeDetailId);
                }
                query.setResultTransformer(CriteriaSpecification.ALIAS_TO_ENTITY_MAP);
                List<Map> list = query.list();
                List<FactorData> voList = new ArrayList<>();
                if (CommonUtils.isNotEmpty(list)) {
                    for (Map map : list) {
                        voList.add(ConversionUtils.convert(map, FactorData.class));
                    }
                } else {
                    voList = new ArrayList<>();
                }
                setResult(voList);
            }
        };
        HibernateSessionTemplate.instance().execute(action);
        return action.getResult();
    }
}